package cn.gov.ssxmzj.utils;

import cn.gov.ssxmzj.entry.BeneficiaryInfo;
import cn.gov.ssxmzj.entry.Result;
import cn.gov.ssxmzj.entry.VillageInfo;
import cn.gov.ssxmzj.mapper.VillageMapper;
import org.apache.poi.ss.usermodel.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.Color;
import java.awt.Font;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.*;
import java.util.List;

public class Utils {

    /**
     * 生成Map
     * @param objects
     * @return
     */
    public static Map asMap(Object... objects) {
        Map m = new HashMap(objects.length / 2 + 1);
        int i = 0;
        for (; i < objects.length - 1; i += 2) {
            m.put(objects[i], objects[i + 1]);
        }

        if (i < objects.length) {
            m.put(objects[i], null);
        }
        return m;
    }

    /**
     * 生成Map
     * @param objects
     * @return
     */
    public static List asList(Object... objects) {
        List l = new ArrayList(objects.length);
        for(Object o:objects){
            l.add(o);
        }
        return l;
    }

    public static boolean isEmpty(List list) {
        return null == list || 0 == list.size();
    }

    public static boolean isEmpty(Map map) {
        return null == map || map.isEmpty();
    }

    public static boolean isEmpty(Object o) {
        return null == o || "".equals(o);
    }

    public static boolean isEmpty(String[] strs) {
        return null == strs || 0 == strs.length;
    }

    /**
     * 校验参数是否为空,为空则返回null
     * @param param
     * @return
     */
    public static String checkNull(String param){
        return isEmpty(param)||"null".equals(param)?null:param;
    }

    private static Map newsTypeNum = asMap("dynamic","1","civil","2","affiche","3","policy","4");

    private static Map newsTypeStr = asMap("1","dynamic","2","civil","3","affiche","4","policy");

    private static Map beneficiaryNumber = asMap("1","农村低保","2","城市低保","3","特困供养",
            "4","优抚对象","5","高龄老人","6","救济救助");

    private static Map beneficiaryName = asMap("农村低保","1","城市低保","2","特困供养",
            "3","优抚对象","4","高龄老人","5","救济救助","6");

    private static List beneficiaryList = asList("农村低保","城市低保","特困供养","优抚对象","高龄老人","救济救助");

    private static Map managerLevelNum = asMap("99","超级管理员","01","普通管理员","02","中级管理员");

    private static Map msgTypeNum = asMap("1","系统公告","2","聊天消息","3","举报消息","4","局长信箱");
    /**
     * 新闻类型转换
     * @param newsType
     * @param isGetNum
     * @return
     */
    public static String changeNewsType(String newsType,boolean isGetNum){
        Map getMap = newsTypeStr;
        if(isGetNum){
            getMap = newsTypeNum;
        }
        return String.valueOf(getMap.get(newsType));
    }

    /**
     * 受惠类型转换
     * @param beneficiary
     * @return
     */
    public static String changeBeneficiaryType(String beneficiary){
        return String.valueOf(beneficiaryNumber.get(beneficiary));
    }
    /**
     * 根据受惠类型内容获取受惠类型
     * @param beneficiary
     * @return
     */
    public static String getBeneficiaryTypeByName(String beneficiary){
        return String.valueOf(beneficiaryName.get(beneficiary));
    }

    /**
     * 工号等级转换
     * @param managerLevel
     * @return
     */
    public static String changeManagerLevel(String managerLevel){
        return String.valueOf(managerLevelNum.get(managerLevel));
    }

    /**
     * 消息类型转换
     * @param msgType
     * @return
     */
    public static String changeMsgType(String msgType){
        return String.valueOf(msgTypeNum.get(msgType));
    }

    /**
     * 性别转换
     * @param sex
     * @return
     */
    public static String changeSex(String sex){
        return "0".equals(sex)?"男":"1".equals(sex)?"女":"保密";
    }

    /**
     * 生成id
     * @param idType
     * @return
     */
    private static String createId(String idType){
        return idType+DateUtils.getDate();
    }

    /**
     * 生成新闻id
     * @return
     */
    public static String createNewsId(){
        return createId("news");
    }

    /**
     * 生成轮播图Id
     * @return
     */
    public static String createShowPicId(){
        return createId("pic");
    }

    /**
     * 生成新闻id
     * @return
     */
    public static String createBeneficiaryId(){
        return createId("ben");
    }

    /**
     * 生成服务id
     * @return
     */
    public static String createOptionId(){
        return createId("opt");
    }

    /**
     * 生成管理员id
     * @return
     */
    public static String createManagerId(){
        return createId("man");
    }

    /**
     * 生成消息id
     * @return
     */
    public static String createMsgId(){
        return createId("msg");
    }

    /**
     * 生成服务id
     * @return
     */
    public static String createServiceId(){
        return createId("ser");
    }

    /**
     * 保存文件
     * @param image
     * @param loadPath
     */
    public static void uploadFile(MultipartFile image,String loadPath) throws Exception{
        InputStream imageIn = null;
        BufferedInputStream in = null;
        OutputStream outPut = null;
        BufferedOutputStream out = null;
        try{
            imageIn = image.getInputStream();
            in = new BufferedInputStream(imageIn);
            outPut = new FileOutputStream(new File(loadPath));
            out = new BufferedOutputStream(outPut);
            byte[] b=new byte[1024];
            int length = 0;
            while((length=in.read(b))!=-1){
                out.write(b,0,length);
            }
            out.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(imageIn != null){
                try {
                    imageIn.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
            if(in != null){
                try {
                    in.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
            if(outPut != null){
                try {
                    outPut.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
            if(out != null){
                try {
                    out.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 解析Excel获取惠民资金数据
     * @param filePath
     * @return
     */
    public static Result getBeneficiaryDataByExcel(String filePath, VillageMapper villageMapper,String optManagerId){
        Workbook work= null;
        try{
            work = WorkbookFactory.create(new FileInputStream(filePath));
        }catch (FileNotFoundException e){
            e.printStackTrace();
            return new Result(Result.ERROR,"获取文件异常，请重新上传后重试","异常信息:"+e.getMessage());
        }catch (IOException o){
            o.printStackTrace();
            return new Result(Result.ERROR,"读取文件异常，请重新上传后重试","异常信息:"+o.getMessage());
        }catch (Exception e){
            e.printStackTrace();
            return new Result(Result.ERROR,"读取文件其他异常，请重新上传后重试","异常信息:"+e.getMessage());
        }
        //设置在读的行数,报错时使用,从第三行开始读取
        int readSheetNum = 0;
        int readLineNum = 2;
        List<BeneficiaryInfo> beneficiaryInfoList = new ArrayList<BeneficiaryInfo>();
        List<VillageInfo> allVillage = villageMapper.getVillageInfo(asMap("validTag","1"));
        if(isEmpty(allVillage)){
            return new Result(Result.ERROR,"未查询到乡镇，无法导入数据，请先确认乡镇数据是否正常","");
        }
        String allVillageNames = getAllVillageName(allVillage);
        String villageName = "";
        try{
            //要读取的数据行数,分别为地址、姓名、身份证号、标准、受惠类型
            int[] readCellNum = new int[]{1,2,5,7};
            int sheetNum = work.getNumberOfSheets();
            for(;readSheetNum<sheetNum;readSheetNum++){
                Sheet sheet = work.getSheetAt(readSheetNum);
                villageName = sheet.getSheetName();
                System.out.println("乡镇:"+villageName+"数据解析中...");
                //sheet页名称即为乡镇名称,根据乡镇名称获取乡镇编码
                String villageId = getVillageIdByName(villageName,allVillage);
                if(isEmpty(checkNull(villageId))){
                    return new Result(Result.ERROR,"根据sheet名称["+villageName+"]未获取到乡镇名，乡镇名全集为："+allVillageNames,beneficiaryInfoList);
                }
                int rowNum = sheet.getLastRowNum();
                //要初始化
                readLineNum = 2;
                ok:for(;readLineNum<=rowNum;readLineNum++){
                    Row row = sheet.getRow(readLineNum);
                    if(!isEmpty(row)){
                        //入库的数据
                        String[] data = new String[4];
                        for(int i=0 ; i < readCellNum.length ; i++){
                            Cell cell = row.getCell(readCellNum[i]);
                            if(isEmpty(cell)){
                                return new Result(Result.ERROR,"解析模板错误：乡镇: "+villageName+" 数据第 "+
                                        (readLineNum+1)+" 行，第"+(readCellNum[i]+1)+"列的值为空，请检查",beneficiaryInfoList);
                            }
                            cell.setCellType(Cell.CELL_TYPE_STRING);
                            String cellName = cell.getStringCellValue();
                            //读到结束标志则停止
                            if(i==0 && StaticUtils.EXCEL_READ_END_FLAG.equals(cellName)){
                                break ok;
                            }
                            if(isEmpty(checkNull(cellName))){
                                return new Result(Result.ERROR,"解析模板错误：乡镇: "+villageName+" 数据第 "+
                                        (readLineNum+1)+" 行，第"+(readCellNum[i]+1)+"列的值为空，请检查",beneficiaryInfoList);
                            }
                            //受惠类型
                            if(readCellNum[i]==7){
                                cellName = getBeneficiaryTypeByName(cellName);
                                if(isEmpty(checkNull(cellName))){
                                    return new Result(Result.ERROR,"解析模板错误：获取受惠类型有误：乡镇: "+
                                            villageName+" 数据第 "+(readLineNum+1)+" 行，受惠类型["+cell.getStringCellValue()+
                                            "]不在约定受惠类型"+beneficiaryList+"中，请检查",beneficiaryInfoList);
                                }
                            }
                            data[i] = cellName;
                        }
                        String beneficiaryId = createBeneficiaryIdForAuto();
                        String createTime = DateUtils.getDate();
                        String isValid = "1";//默认生效
                        BeneficiaryInfo beneficiary = new BeneficiaryInfo(beneficiaryId,data[1],"",data[2],
                                villageId,data[0],data[3],createTime,optManagerId,createTime,optManagerId,isValid,
                                null,null);
                        beneficiaryInfoList.add(beneficiary);
                    }
                }
            }

        }catch (Exception e){
            e.printStackTrace();
            return new Result(Result.ERROR,"解析乡镇["+villageName+"]时数据其他异常，请联系管理员,异常信息:"+e.getMessage(),beneficiaryInfoList);
        }
        return new Result(Result.SUCCESS,"解析成功",beneficiaryInfoList);
    }

    /**
     * 根据乡镇名称获取乡镇id
     * @param villageName
     * @return
     */
    private static String getVillageIdByName(String villageName,List<VillageInfo> villageInfoList){
        String villageId = null;
        int villageCount = 0;
        if(!isEmpty(villageInfoList)){
            for(VillageInfo villageInfo:villageInfoList){
                if (villageInfo.getVillage_name().contains(villageName)){
                    villageId = villageInfo.getVillage_id();
                    villageCount++;
                }
            }
            if(villageCount>1){
                return Result.SERVICE_ERROR;
            }
        }
        return villageId;
    }

    /**
     * 获取所有的乡镇名称
     * @param villageInfoList
     * @return
     */
    private static String getAllVillageName(List<VillageInfo> villageInfoList){
        List<String> villages = new ArrayList<String>();
        for(VillageInfo villageInfo:villageInfoList){
            villages.add(villageInfo.getVillage_name());
        }
        return villages.toString();
    }

    /**
     * 支持批量生成的惠民资金方法
     * @return
     */
    private static String date = DateUtils.getDateNoYear();
    private static int tradeNum = -1;
    private static String createBeneficiaryIdForAuto(){
        if (tradeNum >= 9999) {
            date = DateUtils.getDateNoYear();
            tradeNum = -1;
            return createBeneficiaryIdForAuto();
        }
        tradeNum++;
        String id = String.valueOf(tradeNum);
        while (id.length()<4){
            id = "0"+id;
        }
        return "ben"+date+id;
    }

    /**
     * 生成验证码图片并发送到客户端
     */
    public static void getRandomCode(HttpServletRequest request, HttpServletResponse response) {
        try{
            /*
             * 一,绘图
             */
            // step1,内存映像对象(画布)
            response.reset();
            BufferedImage image = new BufferedImage(135, 35,
                    BufferedImage.TYPE_INT_RGB);
            // step2,获得画笔
            Graphics g = image.getGraphics();
            // step3,给画笔设置颜色
            g.setColor(new Color(255, 255, 255));
            // step4,给画布设置背景颜色
            g.fillRect(0, 0, 135, 35);
            // step5,重新给笔设置颜色
            Random r = new Random();
            g.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));
            g.setFont(new Font(null, Font.ITALIC, 24));
            // step6,生成一个随机数(验证码)
            String number = getNumber();
            HttpSession session =
                    request.getSession();
            session.setAttribute("number", number);
            // 将验证码转换成图片
            g.drawString(addSpaceToNumber(number), 10, 30);
            // step7,加一些干扰线
            for (int i = 0; i < 10; i++) {
                g.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));
                g.drawLine(r.nextInt(135), r.nextInt(37), r.nextInt(135),
                        r.nextInt(37));
            }
            /*
             * 二,压缩图片并输出
             */
            //设置服务器返回的数据类型(图片)
            response.setContentType("image/jpeg");
            //获得字节输出流
            OutputStream ops =
                    response.getOutputStream();
            //压缩图片并输出
            javax.imageio.ImageIO
                    .write(image, "jpeg", ops);
            ops.close();
        }catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 长度为4个字符的验证码(这些字符要求从A~Z,0~9"中选取,排除0,o,1,i)
     *
     * @return
     */
    public static String getNumber() {
        String number = "";
        String chars = "ABCDEFGHJKLMNPQRSTU" + "VWXYZ23456789";
        Random r = new Random();
        for (int i = 0; i < 4; i++) {
            number += chars.charAt(r.nextInt(chars.length()));
        }
        return number;
    }

    /**
     * 给一个字符串的每个字符间增加空格
     * @param number
     * @return
     */
    private static String addSpaceToNumber(String number){
        if(isEmpty(number)){
            return number;
        }
        String retNumber = " ";
        for(int i=0;i<number.length();i++){
            retNumber +=number.charAt(i)+" ";
        }
        return retNumber;
    }

}
